// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-11-6

#ifndef __NET_SOCKET_H_COMMON_SERVLIB__
#define __NET_SOCKET_H_COMMON_SERVLIB__

#pragma once

#include "net_config.h"
#include "net_sockdata.h"
#include "net_transmit.h"

namespace JoyServer
{

void MakeAddress(sockaddr_in& addr, PCSTR pszIP, UINT nPort);
void MakeAddress(sockaddr_in& addr, int b1, int b2, int b3, int b4, UINT nPort);

enum SocketError
{
    SockErr_Ok,
    SockErr_BadFormat,
};

// asynchronous socket object.
// use QueueRecv to post recv operations.
// override OnRecv to process datas received.
// for thread safety, should post only one recv operation on TCP socket. 
// can post several recv operations on UDP socket.
class CJoySocket
{
protected:
    friend class CJoyRecvOverlapped;

    CJoySockData*   m_sockData;
    int m_recvBufLen;

    SOCKET CreateSocket(bool bStream);
    bool DoRecv(int &err);
    bool DoRecvFrom(int &err);

    virtual CJoySockData* CreateData();

    virtual void OnClose();
    virtual void OnError(int err);
    virtual void OnRecv(CJoyTransmitData* recvData, const sockaddr_in& fromAddr);
public:
    CJoySocket();
    virtual ~CJoySocket();

    bool Create(bool bStream, int& err);
    bool Create(bool bStream);
    bool Attach(SOCKET s);
    void Close();
    virtual bool Attach(SOCKET s, bool bStream, int& err);

    virtual bool Send(CJoyTransmitData* sendData, int& err);
    bool Send(CJoyTransmitData* sendData);
    bool Send(const void* buf, int len, int& err);
    bool Send(const void* buf, int len);

    bool SendTo(CJoyTransmitData* sendData, const sockaddr_in& addr, int& err);
    bool SendTo(CJoyTransmitData* sendData, const sockaddr_in& addr);

    bool QueueRecv(int& err);
    bool QueueRecv();
    bool StopRecv();

    bool Bind(const sockaddr_in& addr, int& err);
    bool Bind(const sockaddr_in& addr);
    bool Bind(PCSTR pszIP, UINT nPort, int& err);
    bool Bind(PCSTR pszIP, UINT nPort);

    bool Connect(const sockaddr_in& addr, int& err);
    bool Connect(const sockaddr_in& addr);

    void SetNoTcpDelay(bool bNoDelay);
    bool GetNoTcpDelay();

    bool SetOpt(int optname, const void* optval, int optlen);
    template<typename OptType>
    bool SetOpt(int optname, const OptType& optval)
    {
        return SetOpt(optname, &optval, sizeof(OptType));
    }

    bool GetPeerName(sockaddr_in& addr);
    bool GetPeerName(CString& addrText);
    bool GetPeerIP(CString& addrText);
	void SetSockLinger(SOCKET s,int n);
};


} // namespace JoyServer

#endif  // __NET_SOCKET_H_COMMON_SERVLIB__